<script setup>
import {Content, Layout} from "jiuqi-ui";
import {onMounted, reactive, ref} from "vue";
import NCell, {buildCellSheet, TreeCell} from "n-cell";
import NCELLCSS from "../../utils/NCELLCSS";
import {getTreeNodeByGuid} from "../../utils/TreeHelper"
//================================================【公用相关】============================================================

//================================================【组件通信】============================================================
const props = defineProps({
    memberCount: Number,
    ncellData: Array,
    type: Number
});
//================================================【组件属性】============================================================

//================================================【普通方法】============================================================
//==================================================================【设置ncell容器高度】
let ncellContainerHeight = ref(0)
function setNcellContainerStyle() {
    ncellContainerHeight.value = document.body.clientHeight - 115
}

//==================================================================【初始化ncell】
//ncell对象
let ncell = reactive({})
// 用ref拿到div节点,这一步不能放到initNewCell()中否则程序会报错，应该和vue生命周期有关
const DimensionAndTarget = ref(null)
//设置新报表组件
function initNewCell() {
    // 构建表样
    const data = buildCellSheet('createCell', props.memberCount + 1, 2)
    // 创建表格实例
    ncell = new NCell(
        DimensionAndTarget.value,
        data,
        {
            cell: [
                // 引入树形单元格
                TreeCell
            ]
        },
        {forceShowGridline: true,resizeMode:'all'}
    )

    //设置布局样式
    setNcellStyle()

    //设置监听事件
    setNcellListenEvent()

    //递归设置数值
    recursiveSetData(props.ncellData);

    //设置内容只读
    setContentReadOnly()

}



//==================================================================【设置布局样式】
function setNcellStyle() {
    //表头设置
    for (let j = 0; j < ncell.getColumnCount(); j++) {
        //背景颜色
        ncell.setBackgroundColor(0,j,'#f2f2f2')
        //缩进
        ncell.setIndent(0,j,0.5)
        //对齐方式
        ncell.setHorizontal(0, j, 1)

        //宽度
        ncell.setColumnSize(j, 298)
        //高度
        ncell.setRowSize(0, 30)


        //字体大小
        ncell.setFontSize(0, j, NCELLCSS.fontSize)
        //字体加粗
        ncell.setBold(0, j, NCELLCSS.headerBold)
        //字体颜色
        ncell.setFontColor(0, j, NCELLCSS.fontColor)

        //表头名称
        switch (j){
            case 0:
                props.type === 2 ? ncell.setData(0,j,'分摊维度编码') : ncell.setData(0,j,'成本对象编码')
                break;
            case 1:
                props.type === 2 ? ncell.setData(0,1,'分摊维度名称') : ncell.setData(0,1,'成本对象名称')
                break;
        }
    }



    //非表头行设置
    for (let i = 1; i < ncell.getRowCount(); i++){
        ncell.setRowSize(i, 30) //设置高度
        for (let j = 0; j < ncell.getColumnCount(); j++){
            //对齐方式
            ncell.setHorizontal(i, j, 1)
            //缩进
            ncell.setIndent(i,j,0.5)
        }
    }

    //隐藏行列号
    ncell.hiddenSerialNumberHeader()

    //处理因为隐藏行列号，导致边界消失情况
    ncell.setOffsetX(1)
    ncell.setOffsetY(1)
}

//==================================================================【设置监听事件】
//颜色序列
const bkColor = ['#ffffff00', '#E4F0FF']
//当前鼠标移入单元格的颜色
const currMouseInColor = ref('')
function setNcellListenEvent() {
    // 内置方法，折叠时触发
    ncell.on('rowfold', async (rowIndex) => {
        //获取 点击按钮的行 对应的 树形节点数据
        const treeNode = getTreeNodeByGuid(props.ncellData, ncell.getData(rowIndex, 0))
        //获取 该节点下属节点 对应的 结束行
        const endIndex = rowIndex + treeNode.subDimItemCount
        for (rowIndex = rowIndex + 1; rowIndex <= endIndex; rowIndex++) {
            ncell.hiddenRow(rowIndex)
        }
    })

    // 内置方法，展开时触发
    ncell.on('rowunfold', async (rowIndex) => {
        //获取 点击按钮的行 对应的 树形节点数据
        const treeNode = getTreeNodeByGuid(props.ncellData, ncell.getData(rowIndex, 0))
        //获取 该节点下属节点 对应的 结束行
        const endIndex = rowIndex + treeNode.subDimItemCount
        for (rowIndex = rowIndex + 1; rowIndex <= endIndex; rowIndex++) {
            //是折叠行
            if (ncell.isRowFold(rowIndex)) {
                //折叠行本身应该显示
                ncell.showRow(rowIndex)
                //获取 折叠行 对应节点 的下属节点;下属节点 对应的行 应该隐藏
                const treeNode = getTreeNodeByGuid(props.ncellData, ncell.getData(rowIndex, 0))
                const subNodeCount = treeNode.subDimItemCount
                //跳过处理，继续保持隐藏状态
                rowIndex = rowIndex + subNodeCount;

                //不是折叠行
            }else {
                ncell.showRow(rowIndex)
            }
        }
    })

    //鼠标进入单元格，给该单元格所在行设置背景颜色
    ncell.on('mousein', (res) => {
        //操作表头之下的行
        if (res.entity.r > 0) {
            //存储当前单元格颜色
            currMouseInColor.value = ncell.getBackgroundColor(res.entity.r, res.entity.c)
            const findedIndex = bkColor.findIndex(preFindItem => {
                return preFindItem === currMouseInColor.value
            })
            let showIndex = (findedIndex + 1) % 2
            for (let i = 0; i < ncell.getColumnCount(); i++) {
                ncell.setBackgroundColor(res.entity.r, i, bkColor[showIndex])
            }
        }
    })

    //鼠标离开单元格，给该单元格所在行清除背景颜色
    ncell.on('mouseout', (res) => {
        if (res.entity.r > 0) {
            for (let i = 0; i < ncell.getColumnCount(); i++) {
                ncell.setBackgroundColor(res.entity.r, i, currMouseInColor.value)
            }
        }
    })
}

//==================================================================【递归设置数据】
//从第二行开始不断增加的行号
let allItemCount = ref(1)
function recursiveSetData(arr) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i].subMemberResourceList === null) {
            //将叶子节点维度的值赋给单元格
            ncell.setData(allItemCount.value, 0, arr[i].code)
            ncell.setData(allItemCount.value, 1, arr[i].name)
            //设置缩进
            ncell.setIndent(allItemCount.value, 0, arr[i].tableLevel +  2.1)
            ncell.setIndent(allItemCount.value, 1, arr[i].tableLevel + 0.7)
            //行数加一
            allItemCount.value++
        } else {
            //将父节点维度的值赋给单元格
            ncell.setData(allItemCount.value, 0, arr[i].code)
            ncell.setData(allItemCount.value, 1, arr[i].name)
            //设置缩进
            ncell.setIndent(allItemCount.value, 0, arr[i].tableLevel + 0.7)
            ncell.setIndent(allItemCount.value, 1, arr[i].tableLevel + 0.7)
            //设置单元格为树形单元格
            ncell.setCellType(allItemCount.value, 0, 'tree')
            //行数加一
            allItemCount.value++
            //深度递归遍历
            recursiveSetData(arr[i].subMemberResourceList)
        }
    }
}

//==================================================================【设置内容只读】
function setContentReadOnly() {
    for (let i = 0; i < ncell.getRowCount(); i++) {
        for (let j = 0; j < ncell.getColumnCount(); j++) {
            ncell.setCellReadOnly(i,j)
        }
    }
}

//================================================【生命周期】============================================================
//mounted 初始化页面完成进行操作
onMounted(() => {
    //当浏览器页面大小改变，ncell表格高度对应更新
    window.addEventListener('resize',function(){
        ncellContainerHeight.value = document.body.clientHeight - 115
    })
    setNcellContainerStyle()
    initNewCell();
});
</script>

<template>
    <Layout class="layout">

        <Content>
            <div ref='DimensionAndTarget' style="width: 100%" :style="{height:ncellContainerHeight+'px'}"/>
        </Content>

    </Layout>
</template>

<style scoped>
</style>

